using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using JGSY.CMS.LowCode.Platform.Domain.Entities;
using JGSY.CMS.LowCode.Platform.Domain.Interfaces;
using JGSY.CMS.LowCode.Platform.Infrastructure.CmsDbContext;

namespace JGSY.CMS.LowCode.Platform.Infrastructure.Repositories
{
    /// <summary>
    /// 媒体文件仓储实现
    /// 提供媒体文件数据访问操作的具体实现
    /// </summary>
    public class MediaFileRepository : Repository<MediaFile>, IMediaFileRepository
    {
        public MediaFileRepository(LowCodeDbContext context) : base(context)
        {
        }

        /// <summary>
        /// 基类重写：获取所有媒体文件记录（List 版本）
        /// </summary>
        public override async Task<List<MediaFile>> GetAllAsync()
        {
            return await _context.MediaFiles
                .OrderByDescending(m => m.CreatedAt)
                .ToListAsync();
        }

        /// <summary>
        /// 显式接口实现：返回 IEnumerable 以契合接口
        /// </summary>
        async Task<IEnumerable<MediaFile>> IMediaFileRepository.GetAllAsync()
            => await GetAllAsync();

        /// <summary>
        /// 根据ID获取媒体文件记录
        /// </summary>
        /// <param name="id">媒体文件标识符</param>
        /// <returns>媒体文件实体，如果未找到则返回null</returns>
        public async Task<MediaFile?> GetByIdAsync(long id)
        {
            return await _context.MediaFiles
                .FirstOrDefaultAsync(m => m.Id == id);
        }

        /// <summary>
        /// 根据存储路径获取媒体文件记录
        /// </summary>
        /// <param name="filePath">存储路径</param>
        /// <returns>媒体文件实体，如果未找到则返回null</returns>
        public async Task<MediaFile?> GetByFilePathAsync(string filePath)
        {
            return await _context.MediaFiles
                .FirstOrDefaultAsync(m => m.StoragePath == filePath);
        }

        /// <summary>
        /// 根据MD5哈希值获取媒体文件记录
        /// </summary>
        /// <param name="hash">MD5哈希值</param>
        /// <returns>媒体文件实体，如果未找到则返回null</returns>
        public async Task<MediaFile?> GetByHashAsync(string hash)
        {
            return await _context.MediaFiles
                .FirstOrDefaultAsync(m => m.Md5Hash == hash);
        }

    /// <summary>
    /// 根据分类（或标签）获取媒体文件
    /// </summary>
    /// <param name="category">分类/标签关键字</param>
    /// <returns>媒体文件列表</returns>
    public async Task<IEnumerable<MediaFile>> GetByCategoryAsync(string category)
        {
            // 由于MediaFile实体没有Category属性，这里按文件夹ID查询
            // 如果需要按分类查询，可以考虑添加Category属性或使用Tags
            return await _context.MediaFiles
                .Where(m => m.Tags != null && m.Tags.Contains(category))
                .OrderByDescending(m => m.CreatedAt)
                .ToListAsync();
        }

        /// <summary>
        /// 根据文件类型获取媒体文件
        /// </summary>
        /// <param name="fileType">文件类型</param>
        /// <returns>媒体文件列表</returns>
        public async Task<IEnumerable<MediaFile>> GetByFileTypeAsync(string fileType)
        {
            return await _context.MediaFiles
                .Where(m => m.Type == fileType)
                .OrderByDescending(m => m.CreatedAt)
                .ToListAsync();
        }

        /// <summary>
        /// 分页获取媒体文件列表
        /// </summary>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">页大小</param>
        /// <param name="keyword">搜索关键词</param>
        /// <param name="category">文件分类</param>
        /// <param name="fileType">文件类型</param>
        /// <param name="status">状态过滤</param>
        /// <returns>分页结果</returns>
        public async Task<(IEnumerable<MediaFile> Items, int TotalCount)> GetPagedAsync(
            int pageIndex, 
            int pageSize, 
            string? keyword = null, 
            string? category = null,
            string? fileType = null,
            byte? status = null)
        {
            var query = _context.MediaFiles.AsQueryable();

            // 关键词搜索
            if (!string.IsNullOrWhiteSpace(keyword))
            {
                query = query.Where(m => m.Name.Contains(keyword) || 
                                        (m.Description != null && m.Description.Contains(keyword)));
            }

            // 分类过滤（使用Tags字段模拟分类）
            if (!string.IsNullOrWhiteSpace(category))
            {
                query = query.Where(m => m.Tags != null && m.Tags.Contains(category));
            }

            // 文件类型过滤
            if (!string.IsNullOrWhiteSpace(fileType))
            {
                query = query.Where(m => m.Type == fileType);
            }

            // 状态过滤
            if (status.HasValue)
            {
                query = query.Where(m => m.Status == status.Value);
            }

            var totalCount = await query.CountAsync();
            
            var items = await query
                .OrderByDescending(m => m.CreatedAt)
                .Skip((pageIndex - 1) * pageSize)
                .Take(pageSize)
                .ToListAsync();

            return (items, totalCount);
        }

        /// <summary>
        /// 基类重写：添加并返回实体
        /// </summary>
        public override async Task<MediaFile> AddAsync(MediaFile entity)
        {
            await _context.MediaFiles.AddAsync(entity);
            await _context.SaveChangesAsync();
            return entity;
        }

        /// <summary>
        /// 显式接口实现：接口为 Task 版本
        /// </summary>
        async Task IMediaFileRepository.AddAsync(MediaFile entity)
        {
            _ = await AddAsync(entity);
        }

        /// <summary>
        /// 基类重写：更新并返回实体
        /// </summary>
        public override async Task<MediaFile> UpdateAsync(MediaFile entity)
        {
            _context.MediaFiles.Update(entity);
            await _context.SaveChangesAsync();
            return entity;
        }

        /// <summary>
        /// 显式接口实现：接口为 Task 版本
        /// </summary>
        async Task IMediaFileRepository.UpdateAsync(MediaFile entity)
        {
            _ = await UpdateAsync(entity);
        }

        /// <summary>
        /// 删除媒体文件
        /// </summary>
        /// <param name="id">媒体文件标识符</param>
        /// <returns>删除操作任务</returns>
        public async Task DeleteAsync(long id)
        {
            var entity = await GetByIdAsync(id);
            if (entity != null)
            {
                _context.MediaFiles.Remove(entity);
                await _context.SaveChangesAsync();
            }
        }

        /// <summary>
        /// 批量删除媒体文件
        /// </summary>
        /// <param name="ids">媒体文件ID列表</param>
        /// <returns>删除数量</returns>
        public async Task<int> BatchDeleteAsync(IEnumerable<long> ids)
        {
            var entities = await _context.MediaFiles
                .Where(m => ids.Contains(m.Id))
                .ToListAsync();

            if (entities.Any())
            {
                _context.MediaFiles.RemoveRange(entities);
                await _context.SaveChangesAsync();
            }

            return entities.Count;
        }

        /// <summary>
        /// 增加下载次数
        /// </summary>
        /// <param name="id">媒体文件ID</param>
        /// <returns>是否更新成功</returns>
        public async Task<bool> IncrementDownloadCountAsync(long id)
        {
            var entity = await GetByIdAsync(id);
            if (entity != null)
            {
                entity.DownloadCount++;
                await _context.SaveChangesAsync();
                return true;
            }
            return false;
        }

        /// <summary>
        /// 搜索媒体文件
        /// </summary>
        /// <param name="keyword">搜索关键词</param>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">页大小</param>
        /// <returns>搜索结果</returns>
        public async Task<(IEnumerable<MediaFile> Items, int TotalCount)> SearchAsync(
            string keyword, 
            int pageIndex = 1, 
            int pageSize = 20)
        {
            return await GetPagedAsync(pageIndex, pageSize, keyword);
        }

        /// <summary>
        /// 获取存储统计信息
        /// </summary>
        /// <returns>存储统计信息</returns>
        public async Task<object> GetStorageStatisticsAsync()
        {
            var totalFiles = await _context.MediaFiles.CountAsync();
            var totalSize = await _context.MediaFiles.SumAsync(m => (long?)m.Size) ?? 0;
            
            var statistics = new
            {
                TotalFiles = totalFiles,
                TotalSize = totalSize,
                TotalSizeMB = Math.Round(totalSize / (1024.0 * 1024), 2),
                CategoryStats = await _context.MediaFiles
                    .Where(m => m.Tags != null)
                    .GroupBy(m => m.Tags)
                    .Select(g => new { Category = g.Key, Count = g.Count() })
                    .ToListAsync(),
                TypeStats = await _context.MediaFiles
                    .GroupBy(m => m.Type)
                    .Select(g => new { FileType = g.Key, Count = g.Count() })
                    .ToListAsync()
            };

            return statistics;
        }

        /// <summary>
        /// 清理未使用的文件
        /// </summary>
        /// <returns>清理的文件数量</returns>
        public async Task<int> CleanupUnusedFilesAsync()
        {
            var unusedFiles = await GetUnusedFilesAsync();
            var ids = unusedFiles.Select(f => f.Id);
            return await BatchDeleteAsync(ids);
        }

        /// <summary>
        /// 获取未使用的媒体文件
        /// </summary>
        /// <param name="daysOld">天数阈值</param>
        /// <returns>未使用的媒体文件列表</returns>
        public async Task<IEnumerable<MediaFile>> GetUnusedFilesAsync(int daysOld = 30)
        {
            var cutoffDate = DateTime.UtcNow.AddDays(-daysOld);
            
            return await _context.MediaFiles
                .Where(m => m.CreatedAt < cutoffDate && 
                           m.DownloadCount == 0 &&
                           m.Status == 1) // 假设 1 是正常状态
                .ToListAsync();
        }
    }
}
